﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Text;
using System.IO;
using System.Globalization;
using Gollie.WebCache;
using MySQL.Db;

namespace Gollie
{
	public class LatestOffers : CacheTimeSpanDependency
	{
		public static string cacheKey = "data_latestoffers";
		private string html;
		private Dictionary<int, BrancheInfo> branches;

		public LatestOffers()
			: base(300, new string[] {VendorBranche.cacheKey, CacheConfig.OffersChanged})
		{
		}

		public override void Initialize(params object[] args)
		{
			ResultSetCollection resultSets = Database.Queries.GetLatestOffers();

			uint prevVendorId = 0;
			uint vendorId = 0;

			this.branches = args[0] as Dictionary<int, BrancheInfo>;

			Vendors = new Collection<VendorDetails>();

			OfferCollection offers = null;

			foreach (ResultSet r in resultSets)
			{
				if (r.Count == 0)
					continue;

				vendorId = r.GetUInt32(0, "vendorid");
				if (vendorId != prevVendorId)
				{
					VendorInfo vi = Database.Queries.GetVendor(vendorId);
					offers = new OfferCollection();

					Vendors.Add(new VendorDetails { VendorInfo = vi, Offers = offers });

					prevVendorId = vendorId;
				}
				
				//only one offer will be added, plus the total offers for this vendor
				offers.Add(new Offer { Credit = r.GetDecimal(0, "credit"), Price = r.GetDecimal(0, "price"), Count = r.GetInt32(0, "cnt") });
			}

			this.RenderHtml();
		}

		public static LatestOffers GetInstance()
		{
			return DataCache.GetCacheableObject<LatestOffers>(cacheKey, VendorBranche.GetInstance().Branches);
		}

		private void RenderHtml()
		{
			StringBuilder htmlString = new StringBuilder(1024);
			StringWriter stringWriter = new StringWriter(htmlString);
			HtmlTextWriter writer = new HtmlTextWriter(stringWriter);

			foreach (VendorDetails vd in this.Vendors)
			{
				RenderVendorDiv(writer, vd);
			}

			this.html = htmlString.ToString();
		}

		private void RenderVendorDiv(HtmlTextWriter writer, VendorDetails vd)
		{
			writer.WriteBeginTag("li");
			//writer.WriteAttribute("style", "width:360px;height:240px;");
			writer.Write(HtmlTextWriter.TagRightChar);

			writer.WriteBeginTag("a");
			writer.WriteAttribute("href", "/OffersPerVendor.aspx?v=" + vd.VendorInfo.Id.ToString());
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.WriteBeginTag("div");
			RenderCSS("offer-rotator-item", writer);
			writer.WriteAttribute("style", "background-image: url('" + branches[vd.VendorInfo.Branche].Image + "');");
			writer.Write(HtmlTextWriter.TagRightChar);

			RenderLogoAndName(writer, vd);
			this.RenderOffer(writer, vd.Offers[0]);

			writer.WriteEndTag("div");
			writer.WriteEndTag("a");
			writer.WriteEndTag("li");
		}

		private void RenderLogoAndName(HtmlTextWriter writer, VendorDetails vd)
		{
			writer.WriteBeginTag("table"); writer.Write(HtmlTextWriter.TagRightChar);
			writer.WriteBeginTag("tr"); writer.Write(HtmlTextWriter.TagRightChar);

			writer.WriteBeginTag("td"); writer.Write(HtmlTextWriter.TagRightChar);
			this.RenderLogo(writer, vd);
			writer.WriteEndTag("td");

			writer.WriteBeginTag("td"); writer.Write(HtmlTextWriter.TagRightChar);
			this.RenderName(writer, vd);
			writer.WriteEndTag("td");

			writer.WriteEndTag("tr");
			writer.WriteEndTag("table");
		}

		private void RenderLogo(HtmlTextWriter writer, VendorDetails vd)
		{
			string path = vd.VendorInfo.LogoMediumPath;
			if (string.IsNullOrEmpty(path))
				return;

			writer.WriteBeginTag("div");
			RenderCSS("logo", writer);
			writer.Write(HtmlTextWriter.TagRightChar);

			writer.WriteBeginTag("img");
			writer.WriteAttribute("src", Helper.GetImageSrcAttribute(path));
			writer.WriteAttribute("border", "0");
			writer.Write(HtmlTextWriter.TagRightChar);

			writer.WriteEndTag("div");
		}

		private void RenderName(HtmlTextWriter writer, VendorDetails vd)
		{
			writer.WriteBeginTag("div");
			writer.Write(HtmlTextWriter.TagRightChar);

			writer.WriteBeginTag("span");
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.Write(vd.VendorInfo.BedrijfsNaam);
			writer.WriteEndTag("span");

			writer.WriteBreak();

			writer.WriteBeginTag("span");
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.Write(vd.VendorInfo.Plaats);
			writer.WriteEndTag("span");

			writer.WriteEndTag("div");
		}

		private void RenderOffer(HtmlTextWriter writer, Offer offer)
		{
			CultureInfo ci = CultureInfo.CurrentCulture;
			NumberFormatInfo nfi = ci.NumberFormat;
			string curSym = nfi.CurrencySymbol;

			writer.WriteBeginTag("div");
			RenderCSS("home-star-offer", writer);
			writer.Write(HtmlTextWriter.TagRightChar);

			decimal pay = decimal.Truncate(offer.Price);
			decimal get = decimal.Truncate(offer.Credit);

			string o1 = string.Format("<b>Pay</b> {0}<b>{1:0,0}</b>", curSym, pay);
			string o2 = string.Format("<b>Get</b> {0}<b>{1:0,0}</b>", curSym, get);
			string o3 = offer.Count > 1 ? string.Format("&nbsp;&nbsp;nog {0} {1} <b>></b>", offer.Count - 1, offer.Count == 2 ? "deal" : "deals") : "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;details <b>></b>";

			writer.WriteBeginTag("span");
			RenderCSS("pay", writer);
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.Write(o1);
			writer.WriteEndTag("span");

			writer.WriteBeginTag("span");
			RenderCSS("get", writer);
			writer.Write(HtmlTextWriter.TagRightChar);
			writer.Write(o2);
			writer.WriteEndTag("span");

			if (string.IsNullOrEmpty(o3) == false)
			{
				writer.WriteBeginTag("span");
				RenderCSS("more", writer);
				writer.Write(HtmlTextWriter.TagRightChar);
				writer.Write(o3);
				writer.WriteEndTag("span");
			}

			writer.WriteEndTag("div");
		}

		private void RenderCSS(string className, HtmlTextWriter writer)
		{
			if (string.IsNullOrEmpty(className) == false)
				writer.WriteAttribute("class", className);
		}

		public Collection<VendorDetails> Vendors { get; private set; }

		public string Html
		{
			get { return this.html; }
		}
	}

	public class Offer
	{
		public decimal Credit;
		public decimal Price;
		public int Count;
	}

	public class OfferCollection : Collection<Offer>
	{
	}

	public class VendorDetails
	{
		public VendorInfo VendorInfo;
		public OfferCollection Offers;
	}
}